package com.xiebishe.mylibrary.common.permission

import android.app.Activity
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import io.reactivex.functions.Consumer
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

class PermissionHandler private constructor(val obj: Any) {

    constructor(activity: Activity) : this(obj = activity)
    constructor(fragment: androidx.fragment.app.Fragment) : this(obj = fragment)

    private lateinit var completableDeferred: CompletableDeferred<List<PermissionFail>>
    private val requestCode = 0
    private val activity: Activity? by lazy {
        when (obj) {
            is Activity -> obj
            is androidx.fragment.app.Fragment -> obj.activity
            else -> null
        }
    }


    /**
     * @param permissions 请求响应权限
     * @return 没有取得的权限，如果empty，则所有权限已经获，如果为null 则是被打断
     */
    suspend fun requestPermission(vararg permissions: String): List<PermissionFail>? {
        activity ?: return listOf()
        val deniedPermission = permissions.filter {
            ActivityCompat.checkSelfPermission(activity!!, it) == PackageManager.PERMISSION_DENIED
        }
        if (deniedPermission.isEmpty()) {
            return listOf()
        }

        completableDeferred = CompletableDeferred()
        when (obj) {
            is Activity -> ActivityCompat.requestPermissions(obj, deniedPermission.toTypedArray(), requestCode)
            is androidx.fragment.app.Fragment -> obj.requestPermissions(deniedPermission.toTypedArray(), requestCode)
        }
        return try {
            completableDeferred.await()
        } catch (e: Exception) {
            null
        }

    }

    fun requestPermissionInJava(a: Consumer<List<PermissionFail>>, vararg permissions: String) {
        GlobalScope.launch(Dispatchers.Main) {
            val requestPermission = requestPermission(*permissions)
            a.accept(requestPermission ?: emptyList())
        }
    }

    fun hasPermission(vararg permissions: String): Boolean {
        val deniedPermission = permissions.filter {
            ActivityCompat.checkSelfPermission(activity!!, it) == PackageManager.PERMISSION_DENIED
        }
        return deniedPermission.isEmpty()
    }

    fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (requestCode != this.requestCode || !this::completableDeferred.isInitialized) {
            return
        }
        if (permissions.isEmpty()) {
            completableDeferred.cancel()
            return
        }
        val deniedList = permissions.filterIndexed { index, _ ->
            grantResults[index] == PackageManager.PERMISSION_DENIED
        }
        val map = deniedList.map {
            val shouldShowRequestPermissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(activity!!, it)
            PermissionFail(it, !shouldShowRequestPermissionRationale)
        }
        completableDeferred.complete(map)
    }
}
